package com.tian.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tian.common.CommonResult;
import com.tian.dto.LicensePlateInfoListRespDto;
import com.tian.dto.LicensePlateInfoRespDto;
import com.tian.entity.LicenseEntity;
import com.tian.entity.LicensePlateInfo;
import com.tian.mapper.LicensePlateInfoMapper;
import com.tian.service.LicensePlateInfoService;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * {@code @description:} 城市车牌前缀信息
 *
 * @author tianwc 公众号：Java后端技术全栈
 * 在线刷题 1200+java面试题和1000+篇技术文章：<a href="https://woaijava.cc/">博客地址</a>
 * {@code @date:} 2024-06-06 21:13
 * {@code @version:} 1.0
 */
@Service
public class LicensePlateInfoServiceImpl implements LicensePlateInfoService {

    @Resource
    private LicensePlateInfoMapper licensePlateInfoMapper;
    @Resource
    private RedissonClient redissonClient;

    @Override
    public CommonResult<LicensePlateInfoListRespDto> getLicensePlateInfoByProvinceCode(String provinceCode) {
        String key = "license.plate.province.code_" + provinceCode;
        RBucket<String> bucket = redissonClient.getBucket(key);
        String cache = bucket.get();
        if (cache != null) {
            LicensePlateInfoListRespDto licensePlateInfoListRespDto = JSON.parseObject(cache, LicensePlateInfoListRespDto.class);
            return CommonResult.success(licensePlateInfoListRespDto);
        }

        List<LicensePlateInfo> licensePlateInfoList = licensePlateInfoMapper.selectByProvinceCode(provinceCode);
        if (CollectionUtils.isEmpty(licensePlateInfoList)) {
            return CommonResult.success(new LicensePlateInfoListRespDto());
        }
        LicensePlateInfoListRespDto licensePlateInfoListRespDto = getLicensePlateInfoListRespDto(licensePlateInfoList, bucket);
        return CommonResult.success(licensePlateInfoListRespDto);
    }

    @Override
    public CommonResult<LicensePlateInfoListRespDto> getLicensePlateInfo() {
        String key = "license.plate.province.code.all";
        RBucket<String> bucket = redissonClient.getBucket(key);
        String cache = bucket.get();
        if (cache != null) {
            LicensePlateInfoListRespDto licensePlateInfoListRespDto = JSON.parseObject(cache, LicensePlateInfoListRespDto.class);
            return CommonResult.success(licensePlateInfoListRespDto);
        }
        List<LicensePlateInfo> licensePlateInfos = licensePlateInfoMapper.selectAll();
        if (licensePlateInfos == null) {
            return CommonResult.success(new LicensePlateInfoListRespDto());
        }
        LicensePlateInfoListRespDto licensePlateInfoListRespDto = getLicensePlateInfoListRespDto(licensePlateInfos, bucket);
        return CommonResult.success(licensePlateInfoListRespDto);
    }

    @Override
    public void initData() throws IOException {
        // 读取JSON文件内容
        String jsonString = new String(Files.readAllBytes(Paths.get("D:\\workspace\\charge-station-latest\\charge-service\\charge-user\\charge-user-service\\target\\classes\\carArea.json")));

        // 将JSON字符串解析为JSONObject
        JSONObject jsonObject = JSON.parseObject(jsonString);

        // 获取"codeInfo"数组节点
        JSONArray codeInfoArray = jsonObject.getJSONArray("codeInfo");

        List<LicenseEntity> licenseEntities = new ArrayList<>();
        // 遍历"codeInfo"数组
        for (int i = 0; i < codeInfoArray.size(); i++) {
            JSONObject codeInfoObject = codeInfoArray.getJSONObject(i);
            String hp = codeInfoObject.getString("hp");
            String city = codeInfoObject.getString("city");
            String province = codeInfoObject.getString("province");
            String provinceCode = codeInfoObject.getString("provinceCode");
            String areaCode = codeInfoObject.getString("AreaCode");

            LicenseEntity licenseEntity = new LicenseEntity();
            licenseEntity.setCity(city);
            licenseEntity.setHp(hp);
            licenseEntity.setProvince(province);
            licenseEntity.setProvinceCode(provinceCode);
            licenseEntity.setAreaCode(areaCode);
            licenseEntities.add(licenseEntity);
        }
        List<LicensePlateInfo> licensePlateInfos = new ArrayList<>();

        licenseEntities.forEach(licenseEntity -> {
            LicensePlateInfo record = new LicensePlateInfo();
            record.setCity(licenseEntity.getCity());
            record.setHp(licenseEntity.getHp());
            record.setProvince(licenseEntity.getProvince());
            record.setAreaCode(licenseEntity.getAreaCode());
            record.setProvinceCode(licenseEntity.getProvinceCode());
            licensePlateInfos.add(record);
        });
        for (LicensePlateInfo licensePlateInfo : licensePlateInfos) {
            licensePlateInfoMapper.insert(licensePlateInfo);
        }
    }

    private static LicensePlateInfoListRespDto getLicensePlateInfoListRespDto(List<LicensePlateInfo> licensePlateInfos, RBucket<String> bucket) {
        LicensePlateInfoListRespDto licensePlateInfoListRespDto = new LicensePlateInfoListRespDto();
        List<LicensePlateInfoRespDto> licensePlateInfoRespDtoList = new ArrayList<>();
        licensePlateInfos.forEach(licensePlateInfo -> {
            LicensePlateInfoRespDto licensePlateInfoRespDto = new LicensePlateInfoRespDto();
            licensePlateInfoRespDto.setAreaCode(licensePlateInfo.getAreaCode());
            licensePlateInfoRespDto.setProvince(licensePlateInfo.getProvince());
            licensePlateInfoRespDto.setProvinceCode(licensePlateInfo.getProvinceCode());
            licensePlateInfoRespDto.setCity(licensePlateInfo.getCity());
            licensePlateInfoRespDto.setHp(licensePlateInfo.getHp());
            licensePlateInfoRespDto.setId(licensePlateInfo.getId());
            licensePlateInfoRespDtoList.add(licensePlateInfoRespDto);
        });
        licensePlateInfoListRespDto.setData(licensePlateInfoRespDtoList);
        bucket.set(JSON.toJSONString(licensePlateInfoListRespDto));
        return licensePlateInfoListRespDto;
    }
}
